/*jslint vars:true plusplus:true*/

//=========================================================
// Interactive Digital Media Diploma
// CUFDIG404A_R1: Introduction to Scripting
// Assignment 3
// Author: Ben
// File: background.js
// Description: Display background
//=========================================================

// background object
// shows all of the hills and mountains 
function Background() {
    "use strict";
    
    var self = this;
    var skyColor = 'darkblue';
    var mountainColor = 'cyan';
    var hillColor = 'green';
    var groundColor = 'orange';
    var mountainWidth = 80;
    var mountainHeight = 70;
    var hillWidth = 120;
    var hillHeight = 50;
    var mountainBase = 2 / 5 * window.game.canvas.height;
    var hillBase = 3 / 5 * window.game.canvas.height;
    var groundLevel = 4 / 5 * window.game.canvas.height;
    var hillSpeed = -40;
    var mountainSpeed = -25;
    var baseSpeed = 200;
    var groundPointCount = 30;
    var groundVariance = 6;
    // method to get the base speed of the background scroll
    self.getBaseSpeed = function () {
        return baseSpeed;
    };
    
    // method to get the ground level
    self.getGroundLevel = function () {
        return groundLevel;
    };
    
    var groundHeights = [];
    
    // wrappable hills
    var hillPositions = [ 300, 600, 1050 ];
    
    // wrappable mountains 
    var mountainPositions = [130, 400, 700, 950];

    // function to draw an isoceles triangle with its base on the X axis
    var drawTriangle = function (context, baseX, baseY, width, height, color) {
        context.fillStyle = color;
        context.beginPath();
        context.moveTo(baseX - width, baseY);
        context.lineTo(baseX + width, baseY);
        context.lineTo(baseX, baseY - height);
        context.closePath();
        context.fill();
    };

    
    // method to draw a set of tris along a line
    self.drawLineTris = function (context, positions, yPos, width, height, color) {
        var idx;
        for (idx = 0; idx < positions.length; idx++) {
            drawTriangle(context, positions[idx], yPos, width, height, color);
        }
    };

    
    // draw the background (called by game class)
    self.draw = function (context) {
        context.save();
        var width = context.canvas.width;
        var height = context.canvas.height;
        // Use the identity matrix while clearing the canvas
        context.setTransform(1, 0, 0, 1, 0, 0);

        // draw the sky
        context.fillStyle = skyColor;
        context.fillRect(0, 0, width, mountainBase * height);
        
        // draw the mountain layer
        context.fillStyle = mountainColor;
        context.fillRect(0, mountainBase,  width, (hillBase - mountainBase));
        
        // draw the hill layer
        context.fillStyle = hillColor;
        context.fillRect(0, hillBase,  width, (groundLevel - hillBase));
        
        // draw the ground layer
        context.fillStyle = groundColor;
        //context.fillRect(0, groundLevel, width, height - groundLevel);
        context.beginPath();
        context.moveTo(0, groundLevel);
        var x = 0;
        for(var groundHeightIdx = 0; groundHeightIdx < groundHeights.length; groundHeightIdx++)
        {
            context.lineTo(x, groundHeights[groundHeightIdx]);
            x+= 5;
        }
        context.closePath();
        // Restore the transform
        context.restore();
        
        // hills
        self.drawLineTris(context, hillPositions, hillBase, hillWidth, hillHeight, hillColor);
        
        // mountains
        self.drawLineTris(context, mountainPositions, mountainBase, mountainWidth, mountainHeight, mountainColor);
    };
    
    
    // shift points along x axis. Wrap to screen - used to move/wrap hills and mountains 
    self.shiftPointsX = function (points, shift, margin) {
        var idx = 0;
        for (idx = 0; idx < points.length; idx++) {
            points[idx] += shift;
            while (points[idx] < -margin) {
                points[idx] += window.game.canvas.width + 2 * margin;
            }
            while (points[idx] >= window.game.canvas.width + margin) {
                points[idx] -= window.game.canvas.width + 2 * margin;
            }
        }
    };
    
    
    // update the hills and mountains at different speeds
    self.update = function () {
        self.shiftPointsX(hillPositions, hillSpeed / window.game.frameRate, hillWidth);
        self.shiftPointsX(mountainPositions, mountainSpeed / window.game.frameRate, mountainWidth);
    };
    
    
    self.generateGround = function(){
        for(var idx = 0; idx < groundPointCount; idx++){
            groundHeights.push(groundLevel + (Math.random() * groundVariance * 2) - groundVariance);
        }        
    }
    
    self.generateGround();
}

// set up background as game member (so other subsystems can access it)
window.game.background = new Background();

// add a background subsystem to the game
window.game.addSubsystem(window.game.background);
